package com.das.mechanic_base.base;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

import androidx.annotation.Nullable;

import com.alibaba.android.arouter.launcher.ARouter;
import com.das.mechanic_base.R;
import com.das.mechanic_base.app.X3AppRouterConstants;
import com.das.mechanic_base.app.X3Constent;
import com.das.mechanic_base.app.X3MyApp;
import com.das.mechanic_base.bean.verison.ChangeVersion;
import com.das.mechanic_base.utils.LanguageLayoutInflaterFactory;
import com.das.mechanic_base.utils.LanguageResources;
import com.das.mechanic_base.utils.LanguageUtiles;
import com.das.mechanic_base.utils.X3FileUtils;
import com.das.mechanic_base.utils.X3StringUtils;
import com.das.mechanic_base.utils.X3ToastUtils;
import com.das.mechanic_base.utils.X3VersionUtils;
import com.das.mechanic_base.widget.X3UpdateAppDialog;
import com.downloader.Error;
import com.downloader.OnDownloadListener;
import com.downloader.PRDownloader;
import com.trello.rxlifecycle2.LifecycleTransformer;
import com.trello.rxlifecycle2.android.ActivityEvent;
import com.umeng.analytics.MobclickAgent;
import com.yhao.floatwindow.FloatWindow;

import java.io.File;
import java.lang.reflect.Method;
import java.util.List;

import butterknife.ButterKnife;
import butterknife.Unbinder;
import me.imid.swipebacklayout.lib.SwipeBackLayout;

import static android.webkit.WebView.enableSlowWholeDocumentDraw;

/**
 * @author chensi
 */
public abstract class X3BaseActivity<P extends X3BasePresenter> extends X3SwipeBackActivity implements X3IBaseView {

    protected P mPresenter;

    private Unbinder unbinder;

    public BaseViewProxy viewProxy;

    private X3UpdateAppDialog updateAppDialog;

    protected abstract int getLayoutId();

    protected abstract void initView();

    InputMethodManager im;

    protected SwipeBackLayout swipeBackLayout;

    private String updateType;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        getLayoutInflater().setFactory2(new LanguageLayoutInflaterFactory(this));
        super.onCreate(savedInstanceState);
        if (android.os.Build.VERSION.SDK_INT >= 21) {
            enableSlowWholeDocumentDraw();
        }
        int layoutId = getLayoutId();
        if (layoutId != 0) {
            setContentView(layoutId);
        }

        if (isTransparent()) {
            getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
        }

        X3MyApp.getInstance().addActivity(this);
        unbinder = ButterKnife.bind(this);
        viewProxy = new BaseViewProxy(this);
        mPresenter = createPresenter();
        if (mPresenter != null) {
            mPresenter.attachView(this);
        }

        inSwipe();

        initView();
    }

    /**
     * 是否透明背景
     * @return
     */
    @Override
    public boolean isTransparent() {
        return false;
    }

    @Override
    protected void onResume() {
        super.onResume();
        LanguageUtiles.updateResources(this,LanguageUtiles.getAppLocale(this).locale);
        if (FloatWindow.get("Visit") != null) {
            boolean live = FloatWindow.get("Visit").isShow();
            if (!live) {
                FloatWindow.get("Visit").show();
            }
        }
        if (FloatWindow.get("Live") != null) {
            boolean live = FloatWindow.get("Live").isShow();
            if (!live) {
                FloatWindow.get("Live").hide();
            }
        }
        MobclickAgent.onResume(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (FloatWindow.get("Live") != null) {
            FloatWindow.get("Live").hide();
        }
        super.onPause();
        if (FloatWindow.get("Visit") != null) {
            FloatWindow.get("Visit").hide();
        }
        MobclickAgent.onPause(this);
    }

    @Override
    public void applyOverrideConfiguration(Configuration overrideConfiguration) {
        // 兼容androidX在部分手机切换语言失败问题
        if (overrideConfiguration != null) {
            int uiMode = overrideConfiguration.uiMode;
            overrideConfiguration.setTo(getBaseContext().getResources().getConfiguration());
            overrideConfiguration.uiMode = uiMode;
        }
        super.applyOverrideConfiguration(overrideConfiguration);
    }

    public void reStart() {
        ARouter.getInstance().build(X3AppRouterConstants.Router.SPLASH_MAIN)
                .withTransition(R.anim.slide_in_right, R.anim.slide_out_left)
                .withFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
                .navigation();
        X3MyApp.getInstance().clearActivities();
    }

    protected abstract P createPresenter();

    @Override
    public void startActivity(Intent intent) {
        super.startActivity(intent);
        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
    }

    @Override
    public void startActivityForResult(Intent intent, int requestCode) {
        super.startActivityForResult(intent, requestCode);
        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
    }

    public void inSwipe() {
        swipeBackLayout = getSwipeBackLayout();
        //设置滑动模式
        swipeBackLayout.setEnableGesture(true);
        //获取屏幕的宽度
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int phoneWidth = dm.widthPixels;
        //设置侧滑的区域为屏幕宽度的1/2，如果不设置系统默认为50dip
        swipeBackLayout.setEdgeSize(phoneWidth / 5);
        swipeBackLayout.setEdgeTrackingEnabled(SwipeBackLayout.EDGE_LEFT);
    }

    @Override
    public void finish() {
        super.finish();
        overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时则不能隐藏
     *
     * @param v
     * @param event
     * @return
     */
    protected boolean isShouldHideKeyboard(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {
            int[] l = {0, 0};
            v.getLocationInWindow(l);
            int left = l[0],
                    top = l[1],
                    bottom = top + v.getHeight(),
                    right = left + v.getWidth();
            return !(event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom);
        }
        // 如果焦点不是EditText则忽略，这个发生在视图刚绘制完，第一个焦点不在EditText上，和用户用轨迹球选择其他的焦点
        return false;
    }

    /**
     * 获取InputMethodManager，隐藏软键盘
     *
     * @param token
     */
    protected void hideKeyboard(IBinder token) {
        if (token != null) {
            im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            if (im != null) {
                im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        try {
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                View v = getCurrentFocus();
                if (isShouldHideKeyboard(v, ev)) {
                    hideKeyboard(v.getWindowToken());
                    if (v != null) {
                        v.clearFocus();
                    }
                }
            }
            return super.dispatchTouchEvent(ev);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public void showSuccess(String successMsg) {
        X3ToastUtils.showMessage(successMsg);
    }

    @Override
    public void showFaild(String errorMsg) {
        X3ToastUtils.showMessage(errorMsg);
    }

    public void hintKeyBoard() {
        //拿到InputMethodManager
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        //如果window上view获取焦点 && view不为空
        if (imm.isActive() && getCurrentFocus() != null) {
            //拿到view的token 不为空
            if (getCurrentFocus().getWindowToken() != null) {
                //表示软键盘窗口总是隐藏，除非开始时以SHOW_FORCED显示。
                imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    }

    @Override
    public void showNoNet() {
        //ToastUtils.showShort("网络连接错误!");
    }

    @Override
    public <T> LifecycleTransformer<T> bindToLife() {
        return this.bindUntilEvent(ActivityEvent.DESTROY);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbinder.unbind();
        hintKeyBoard();
        if (updateAppDialog != null) {
            updateAppDialog.dismiss();
        }
        if (mPresenter != null) {
            mPresenter.detachView();
            mPresenter = null;
        }
        if (viewProxy != null) {
            viewProxy.destroy();
        }
        X3MyApp.getInstance().removeActivity(this);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (getSupportFragmentManager().getBackStackEntryCount() <= 0) {
            finish();
        } else {
            getSupportFragmentManager().popBackStack();
        }
    }

    public void showLoading(String text) {
        viewProxy.showLoading(text);
    }

    public void setLoadingNoCancel() {
        viewProxy.setCancelNo();
    }

    public void hideLoading() {
        viewProxy.hideLoading();
    }

    public void showToast(String text) {
        viewProxy.showToast(text);
    }

    public void updateAppVersion(final ChangeVersion changeVersion, String newVersion) {
        PackageInfo packageInfo = null;
        try {
            packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
            String versionName = packageInfo.versionName;
            int i = X3VersionUtils.compareVersions(versionName, newVersion);
            if (i != 1) {
                return;
            }

            // 如果版本后缀不一致那么不用进行下一步更新操作
            if (!X3Constent.VERSION_SUFFIX.equals(changeVersion.versionSuffix)) {
                return;
            }
            String currentVersionName = X3StringUtils.isEmpty(X3Constent.VERSION_SUFFIX) ? versionName : versionName + "_" + X3Constent.VERSION_SUFFIX;
            List<String> compatibleVersionSet = changeVersion.compatibleVersionSet;
            // 当前版本如果在兼容版本里面则不提醒
            if (!X3StringUtils.isListEmpty(compatibleVersionSet) && compatibleVersionSet.contains(currentVersionName)) {
                return;
            }

            if (!"ANDROID".equals(changeVersion.platform)) {
                return;
            }

            // 当前版本号
            List<String> weakReminderVersionSet = changeVersion.weakReminderVersionSet;
            List<String> strongReminderVersionSet = changeVersion.strongReminderVersionSet;
            // 判断当前版本号属于是那种更新类型
            if (!X3StringUtils.isListEmpty(weakReminderVersionSet) && weakReminderVersionSet.contains(currentVersionName)) {
                this.updateType = X3Constent.WEAK_UPDATE;
            }else if (!X3StringUtils.isListEmpty(strongReminderVersionSet) && strongReminderVersionSet.contains(currentVersionName)) {
                this.updateType = X3Constent.STRONG_UPDATE;
            }else {
                this.updateType = X3Constent.FORCED_UPDATE;
            }

            File appFile;
            if (X3StringUtils.isEmpty(changeVersion.versionSuffix)) {
                appFile = new File(X3FileUtils.getStoragePath(this, X3FileUtils.APP_STORAGE_PATH) + "MECHANIC_" + changeVersion.appVersion + ".apk");
            }else {
                appFile = new File(X3FileUtils.getStoragePath(this, X3FileUtils.APP_STORAGE_PATH) + "MECHANIC_" + changeVersion.appVersion + "_"  + changeVersion.versionSuffix + ".apk");
            }

            if (appFile.exists()) {
                // TODO 如果app 已经下载 那么直接提示用户安装
                showUpdateDialog(changeVersion,updateType);
            }else {
                if (X3Constent.FORCED_UPDATE.equals(updateType)) {
                    showUpdateDialog(changeVersion,updateType);

                }else {
                    // 如果app还没有下载 开启下载
                    PRDownloader.download(X3Constent.isChina() ? changeVersion.downloadUrlQiniu : changeVersion.downloadUrl, X3FileUtils.getStoragePath(this, X3FileUtils.APP_STORAGE_PATH), appFile.getName())
                            .build()
                            .setOnProgressListener(progress -> {
                                int l = (int) (progress.currentBytes * 100 / progress.totalBytes);
                            })
                            .start(new OnDownloadListener() {
                                @Override
                                public void onDownloadComplete() {
                                    //TODO 提示用户安装
                                    showUpdateDialog(changeVersion,updateType);
                                }

                                @Override
                                public void onError(Error error) {
                                }

                            });
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 显示兼容版本
     * @param changeVersion
     */
    private void showUpdateDialog(ChangeVersion changeVersion, String updateType){
        if (isFinishing()) {
            return;
        }
        if (updateAppDialog == null) {
            updateAppDialog = new X3UpdateAppDialog(this);
        }
        updateAppDialog.showDownType(updateType,changeVersion);
        showMineDownNotice(updateType);
    }

    @Override
    public void showMineDownNotice(String showType) {}

    private Resources resources;

    @Override
    public Resources getResources() {
        if (resources == null) {
            resources = new LanguageResources(super.getResources());
        }
        Configuration config = new Configuration();
        config.setToDefaults();
        resources.updateConfiguration(config,resources.getDisplayMetrics());
        return resources;
    }

    public void setDrawDuringWindowsAnimating(View view) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M
                || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            // 1 android n以上  & android 4.1以下不存在此问题，无须处理
            return;
        }
        // 4.2不存在setDrawDuringWindowsAnimating，需要特殊处理
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            handleDispatchDoneAnimating(view);
            return;
        }
        try {
            // 4.3及以上，反射setDrawDuringWindowsAnimating来实现动画过程中渲染
            ViewParent rootParent = view.getRootView().getParent();
            Method method = rootParent.getClass()
                    .getDeclaredMethod("setDrawDuringWindowsAnimating", boolean.class);
            method.setAccessible(true);
            method.invoke(rootParent, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * android4.2可以反射handleDispatchDoneAnimating来解决
     */
    private void handleDispatchDoneAnimating(View paramView) {
        try {
            ViewParent localViewParent = paramView.getRootView().getParent();
            Class localClass = localViewParent.getClass();
            Method localMethod = localClass.getDeclaredMethod("handleDispatchDoneAnimating");
            localMethod.setAccessible(true);
            localMethod.invoke(localViewParent);
        } catch (Exception localException) {
            localException.printStackTrace();
        }
    }


}
